package com.goods.shop.service.third;

import cn.hutool.core.io.FileUtil;
import com.goods.shop.service.AbstractService;
import com.goods.shop.service.model.third.OrderModel;
import com.goods.shop.service.model.third.OrderTaskModel;
import com.goods.shop.util.*;
import com.sun.javafx.scene.control.skin.TableCellSkin;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.FileSystemUtils;

import java.io.*;
import java.time.LocalDateTime;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BiGaoService extends AbstractService {
    private Pattern pattern=Pattern.compile("<body>(.*?)</body>");
    private Pattern couponNoPattern=Pattern.compile("<couponNo>(.*?)</couponNo>");
    private AtomicInteger count=new AtomicInteger(0);
    public String generateXML(OrderModel order){
        String merchantNo=order.getMerchantNo();
        String userName=order.getUserName();
        String mobile=order.getMobile();
        String prodId=order.getProdId();
        String orderNo=order.getOrderNo();
        String sellerKey=order.getSellerKey();
        StringBuilder xmlBuilder=new StringBuilder("");
        xmlBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
        xmlBuilder.append("<Request>");
        xmlBuilder.append("<head><Version>1.0</Version><SpId>")
                .append(merchantNo).append("</SpId>")
                .append("<Zip>false</Zip><Encrypt>true</Encrypt></head>");

        xmlBuilder.append("<body>");

        StringBuilder bodyBuilder=new StringBuilder("");
        bodyBuilder.append("<UserName>").append(userName).append("</UserName>");
        bodyBuilder.append("<Mobile>").append(mobile).append("</Mobile>");
        bodyBuilder.append("<ProdId>").append(prodId).append("</ProdId>");
        bodyBuilder.append("<operationType>").append(1).append("</operationType>");
        bodyBuilder.append("<Count>").append(1).append("</Count>");
        String locaTime= TimeUtils.formatter(LocalDateTime.now());
        bodyBuilder.append("<OrderDate>").append(locaTime).append("</OrderDate>");
        bodyBuilder.append("<OrderNo>").append(orderNo).append("</OrderNo>");
        String encryptBody="";
        try {
            encryptBody=new String(Base64Utils.encode(AESUtils.encrypt(bodyBuilder.toString().getBytes(),sellerKey)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        xmlBuilder.append(encryptBody);
        xmlBuilder.append("</body>");

        xmlBuilder.append("</Request>");
        return xmlBuilder.toString();
    }

    /**
     *
     * @param order----常规固定的值
     * @param taksModel-----从第几个到第几个结束，以及存储到的对应的文件，每个线程是不一样的
     */
    public void execute(OrderModel order,OrderTaskModel taksModel){
        BufferedWriter writer=null;

        String url=order.getUrl();
        String sellerKey=order.getSellerKey();
        int start=taksModel.getStart();
        int end=taksModel.getEnd();
        String filePath=taksModel.getFilePath();
        try {
            writer=new BufferedWriter(new FileWriter(filePath));
            for(int i=start;i<end;i++){
                String orderNo="EO"+System.nanoTime()+String.format("%06d",i);
                String mobile="13"+String.format("%09d",i);

                order.setOrderNo(orderNo);
                order.setMobile(mobile);
//                logger.info("OrderNo:{},mobile:{}",orderNo,mobile);
                String xml=this.generateXML(order);
//            logger.info("xml={}",xml);
                try {
//                    logger.info("filePath={}",filePath);

                    String response= HttpRequest.sendPost(url,xml,false,"",0);
                    int index=count.getAndIncrement();
                    if(index%100==0){
                        logger.info("执行到:{}",index);
                    }
                    Matcher matcher=pattern.matcher(response);
                    if(matcher.find()){
                        String enBody=matcher.group(1);
                        String body=new String(AESUtils.decrypt(Base64Utils.decode(enBody),sellerKey));
                        logger.info("body={}",body);
                        Matcher couponMatcher=couponNoPattern.matcher(body);

                        if(couponMatcher.find()){
                            String line=orderNo+","+couponMatcher.group(1);
                            writer.write(line);
                            writer.newLine();
                            logger.info("line={}",line);
                        }


                    }
//                    String line=orderNo;
//                    writer.write(line);
//                    writer.newLine();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(writer!=null){
                try {
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void composFile(String sourceDir,String destFile)throws Exception{
        File dir=new File(sourceDir);
        File[] files=dir.listFiles();
        BufferedWriter writer=new BufferedWriter(new FileWriter(destFile));
        String line=null;
        for(File file:files){
            BufferedReader reader=new BufferedReader(new FileReader(file));
            while((line=reader.readLine())!=null){
                writer.write(line);
                writer.newLine();
            }
            writer.flush();
            if(reader!=null)reader.close();
        }
        if(writer!=null){
            writer.close();
        }
    }
    public static void main(String[] args) {
        OrderModel order=new OrderModel();
        BiGaoService service=new BiGaoService();
        order.setMerchantNo("BG001");//TODO
        order.setUrl("http://120.79.254.27/minsheng/synchronizedOrder");//TODO
        order.setSellerKey("0E9fyqztZopg8CXrPRZDvg==");//TODO
        order.setProdId("bgtxspyk001");//TODO

        int threadPools=50;//TODO 线程数量
        int start=1;
        int end=10000;//包含这个TODO

        ExecutorService executorService= Executors.newCachedThreadPool();
        int totalNums=end-start+1;
        int threadCapicity=totalNums%threadPools==0?totalNums/threadPools:totalNums/threadPools+1;
        String dir="D:/jd/bigao";
        String filePath=dir+"/code-{}.txt";
//        logger.info("start to run....");
        int realThreadPools=threadPools;

        for(int i=0;i<threadPools;i++){
            int threadStart=start+i*threadCapicity;
            if(threadStart>end){
                realThreadPools=i;
//                logger.info("i={},threadStart={}",i,threadStart);
                break;
            }
        }
//        logger.info("readlThreadPools={},threadCapicity={},totalNums={}",realThreadPools,threadCapicity,totalNums);
        CountDownLatch latch=new CountDownLatch(realThreadPools);
        for(int i=0;i<realThreadPools;i++){
            OrderTaskModel taskModel=new OrderTaskModel();
            int threadStart=start+i*threadCapicity;
            int threadEnd=threadStart+threadCapicity>totalNums?totalNums+1:threadStart+threadCapicity;
            taskModel.setStart(threadStart);
            taskModel.setEnd(threadEnd);
            String fileIndex=String.format("%06d",i);
            String path=filePath.replaceAll("\\{\\}",fileIndex);
            taskModel.setFilePath(path);

//            logger.info("threadStart={},threadEnd={},path={}",threadStart,threadEnd,path);
            Thread taskThread=new BigGaoThread(order,taskModel,service,latch);
            executorService.execute(taskThread);

        }

        try {
            latch.await();
//            logger.info("end  run....");
            executorService.shutdown();
            String destFile=dir+"/result.txt";
            service.composFile(dir,destFile);
        } catch (Exception e) {
            e.printStackTrace();
        }

//
    }
}
